#include "js-engine.h"
static JSClass gadgetClass =
    { "gadget", 0,
      JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
      JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
      JSCLASS_NO_OPTIONAL_MEMBERS
    };

static JSClass debugClass = 
    { "debug", 0,
      JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
      JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
      JSCLASS_NO_OPTIONAL_MEMBERS
    };
static JSBool debug_error(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
static JSBool debug_trace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
static JSBool debug_warning(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);

struct JSFunctionSpec debug_methods[] = 
    {
	{"error", debug_error, 1, 0, 0},
	{"trace", debug_trace, 1, 0, 0}, 
	{"warning", debug_warning, 1, 0, 0},
    };
static JSBool storage_extract(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
static JSBool storage_openText(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
struct JSFunctionSpec storage_methods[] = {
    {"extract", storage_extract, 1, 0, 0},
    {"openText", storage_openText, 1, 0, 0},
};

static JSClass storageClass = 
    { "storage", 0,
      JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
      JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
      JSCLASS_NO_OPTIONAL_MEMBERS
    };

static JSBool debug_error(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    g_return_val_if_fail(argc == 1,JS_FALSE);
    if(JSVAL_IS_STRING(argv[0]))
	g_print("Gadget Error: %s\n",JS_GetStringBytes(JSVAL_TO_STRING(argv[0])));
    return JS_TRUE;
}
static JSBool debug_trace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    g_return_val_if_fail(argc == 1,JS_FALSE);
    if(JSVAL_IS_STRING(argv[0]))
	g_print("Gadget Trace: %s\n",JS_GetStringBytes(JSVAL_TO_STRING(argv[0])));
    return JS_TRUE;
}
static JSBool debug_warning(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    g_return_val_if_fail(argc == 1,JS_FALSE);
    if(JSVAL_IS_STRING(argv[0]))
	g_print("Gadget Warning: %s\n",JS_GetStringBytes(JSVAL_TO_STRING(argv[0])));
    return JS_TRUE;
}

static JSBool storage_extract(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    JSString *str;
    g_warning("not implemented.");
    g_return_val_if_fail(argc == 1, JS_FALSE);
    str = JS_NewStringCopyZ(cx, "storage_extract is not implemented.");
    *rval = STRING_TO_JSVAL(str);
    return JS_TRUE;
}

static JSBool storage_openText(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    JSString *str;
    g_warning("not implemented.");
    g_return_val_if_fail(argc == 1, JS_FALSE);
    str = JS_NewStringCopyZ(cx, "storage_openText is not implemented.");
    *rval = STRING_TO_JSVAL(str);
    return JS_TRUE;
}

JSObject *gadgetClass_init(js_engine *engine, JSObject *view)
{
    jsval debug_val, storage_val;
    JSObject *gadget = JS_DefineObject(engine->cx, view, "gadget", &gadgetClass, engine->glob, JSPROP_PERMANENT);
    JSObject *debug = JS_DefineObject(engine->cx, gadget, "debug", &debugClass, NULL, JSPROP_PERMANENT);
    JSObject *storage = JS_DefineObject(engine->cx, gadget, "storage", &storageClass, NULL, JSPROP_PERMANENT);

    g_return_val_if_fail(JS_DefineFunctions(engine->cx, debug, debug_methods), FALSE);
    g_return_val_if_fail(JS_DefineFunctions(engine->cx, storage, storage_methods), FALSE);

    debug_val = OBJECT_TO_JSVAL(debug);
    storage_val = OBJECT_TO_JSVAL(storage);
    JS_SetProperty(engine->cx, view, "debug", &debug_val); 
    JS_SetProperty(engine->cx, view, "storage", &storage_val); 
    storage = JS_DefineObject(engine->cx, view, "storage", &storageClass, NULL, JSPROP_PERMANENT);
    g_return_val_if_fail(gadget, FALSE);
    g_return_val_if_fail(debug, FALSE);
    g_return_val_if_fail(storage, FALSE);
    g_return_val_if_fail(JS_DefineFunctions(engine->cx, debug, debug_methods), FALSE);
    g_return_val_if_fail(JS_DefineFunctions(engine->cx, storage, storage_methods), FALSE);

    return NULL;
}
